package com.remoter.provider.internal;

import java.io.IOException;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.remoter.basic.configure.IConfiguration;
import com.remoter.basic.configure.support.AbstractConfiguration;
import com.remoter.basic.provider.support.AbstractProvider;
import com.remoter.basic.task.ITask;
import com.remoter.basic.task.ITaskCallBack;
import com.remoter.basic.util.AbortPolicyWithReport;
import com.remoter.basic.util.Final;
import com.remoter.basic.util.NamedThreadFactory;
import com.remoter.basic.util.ServiceLoader.MetaName;
import com.remoter.provider.internal.util.FinalProviderInternal;

/**
 * @author			koko
 * @date 			2017-08-08 18:40:13
 * @description 	类功能说明
 */
@MetaName("internal")
public class InternalProvider extends AbstractProvider{
	
	private ListeningExecutorService listeningExecutorService;
	private IConfiguration configuration;
	
	public InternalProvider(){
		this.configuration = AbstractConfiguration.getConfiguration();
	}
	
	@Override
	public void submit(ITask task, ITaskCallBack taskCallBack) {
		if(null == listeningExecutorService){
			synchronized(InternalProvider.class){
				if(null == listeningExecutorService){
					String taskName = this.configuration.getOption(FinalProviderInternal.O_VAL_TASK_NAME);
					ThreadPoolExecutor executor = new ThreadPoolExecutor(
							Final.PROCRESS,Final.PROCRESS*100,
							1000,
							TimeUnit.MILLISECONDS,
			                new LinkedBlockingQueue<Runnable>(Final.PROCRESS*500),
			                new NamedThreadFactory(taskName,true),new AbortPolicyWithReport(taskName));
					listeningExecutorService = MoreExecutors.listeningDecorator(executor);
				}
			}
		}
		ListenableFuture<Boolean> future = listeningExecutorService.submit(task);
		Futures.addCallback(future,taskCallBack,listeningExecutorService);
	}

	@Override
	public void close() throws IOException {
		super.close();
		if(null != listeningExecutorService){
			synchronized(InternalProvider.class){
				if(null != listeningExecutorService){
					listeningExecutorService.shutdown();
				}
			}
		}
	}
	
}